package com.github.ghsea.sso.cas;

import com.github.ghsea.sso.cas.utils.Digests;
import com.github.ghsea.sso.cas.utils.Encodes;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author guhai
 * MD5加盐Hash与密码比对
 */
public class HashSaltPasswordEncoder implements PasswordEncoder {

    /**
     * Hash次数
     */
    private final int HASH_COMPUTE_TIMES = 1024;

    private final int SALT_LENGTH = 12;

    @Override
    public String encode(CharSequence input) {
        return input.toString();
    }

    /**
     * @param input             页面上输入的密码
     * @param encryptedPassword 从数据库里取出的hash加盐的密码
     * @return
     */
    @Override
    public boolean matches(CharSequence input, String encryptedPassword) {
        String plainPassword = input.toString();
        byte[] salt = computeSalt(encryptedPassword);
        byte[] hashPassword = Digests.sha1(plainPassword.getBytes(), salt, HASH_COMPUTE_TIMES);
        String recomputedPassword = Encodes.encodeHex(salt) + Encodes.encodeHex(hashPassword);

        return recomputedPassword.equals(encryptedPassword);
    }

    private byte[] computeSalt(String encrypted) {
        return decodeHex(encrypted.substring(0, SALT_LENGTH));
    }

    public byte[] decodeHex(String input) {
        try {
            return Hex.decodeHex(input.toCharArray());
        } catch (DecoderException e) {
            throw new RuntimeException(e);
        }
    }

    public String encryptPassword(String plainPassword) {
        byte[] salt = Digests.generateSalt(SALT_LENGTH / 2);
        byte[] hashPassword = Digests.sha1(plainPassword.getBytes(), salt, HASH_COMPUTE_TIMES);
        return Encodes.encodeHex(salt) + Encodes.encodeHex(hashPassword);
    }

}
